PIC Tutorial Six - I2C EEPROM Programming


These tutorials require the Main Board, the LCD Board, and various of the I2C Boards, as written the tutorials use the LCD Board on PortA and the I2C Boards on PortB - although these could easily be swapped over, as the I2C Boards don't use either of the two 'difficult' pins for PortA, pins 4 and 5, as outputs. Download zipped tutorial files.

As with the LCD Tutorial, the idea is to implement a reusable set of I2C routines.

Rather than showing the routines on the page as with earlier tutorials (they are getting quite lengthy now), I'm only going to store them in the pages download ZIP file so you will need to download them. As the I2C tutorials use a number of different boards, each section is headed by the I2C boards required in bold type.

I2C is a protocol designed by Philips Semiconductors, and is for communications between I/C's over a two wire synchronous serial bus, devices are classed as either 'Master' or 'Slave', for our purposes the Main Board processor is the 'Master', and any other devices are 'Slaves'. The initial tutorials use a 24C04, a 512 byte EEPROM memory chip, commonly used for storing the settings in modern TV's and VCR's, where they are used to store all the customer settings (tuning, volume, brightness etc.) and the internal calibration values for the set, which are normally accessed through a special 'service mode'. These chips provide non-volatile memory as a series of 256 byte 'pages', so the 24C04 provides two 'pages' giving 512 bytes of memory. The 24C02 uses 'standard addressing', which gives the 256 byte page limit, other larger chips use 'extended addressing', giving a possible 16 bit address space, I've used a 24C256 which uses a 15 bit address space, giving 32,768 of memory space. To address these you require two bytes of address data, the programs already include these (but commented out), I've uncommented them for copies of the first two tutorials and called them 6_1a and 6_2a, if you want to use an EEPROM larger than a 24C16 you will need to use these extended addressing versions.

I2C EEPROM Board
The first tutorial writes sequential numbers through one entire page of memory, and then reads them back, 4 bytes at a time, displaying them on the LCD, separated by about half a second between updates. The second tutorial demonstrates 'sequential writing', the first tutorial uses 'byte writing' (which is why it displays 'Writing..' for a couple of seconds) - a write is fairly slow to EEPROM, taking around 10mS to complete - 'sequential writing' allows you to store a number of bytes in RAM inside the EEPROM chip (a maximum of 8 for the 24C04) and then write them all to EEPROM with a single write delay. Tutorial 2 writes 4 bytes at once, to demonstrate how this is done. The third tutorial is simply a cut-down version of the first, I've included it as a useful tool, it simply reads one page of the EEPROM and displays it as tutorial 1 does - useful for checking the contents of an EEPROM. You can deal with the EEPROM write delay in a couple of ways, firstly you can introduce a software delay, and this option is included in the tutorials (but commented out), or you can keep checking until the chip is ready, this is the method I've used in these tutorials, although if you want you can comment that line out and un-comment the 'call delay10' line instead.

I2C Clock Board, and I2C Switch Board
Now we move onto the I2C Clock board, basically we use exactly the same I2C routines, the only difference being in the way we manipulate the data, we need to read the clock registers from the chip (using a sequential read), apply a little processing, and then display them on the LCD. Actually setting the clock is somewhat more complicated, and the biggest difference is the routines for reading the switch board, and setting the clock chip values - which are then written back to the chip with a sequential write. The four buttons used are (from left to right), 'Set', 'Up', 'Down', and 'Next' - in the initial display mode the only button which has an effect is the 'Set' button, this jumps to the 'Clock Set' mode, and starts a flashing cursor on the tens of hours. From this point all four buttons work, pressing 'Set' again will return to display mode, updating the clock values (and zeroing the seconds). Pressing 'Up' will increase the value under the cursor, and 'Down' will decrease the value, with '0' being the lower limit, and '9' being the upper one - I don't currently take account of the different maximum values for particular digits (i.e. tens of hours doesn't go higher than 2), but rely on setting them sensibly. The 'Next' button moves on to the next digit, and if pressed while on the last digit (years units) will return to display mode, just like pressing the 'Set' button. I also don't currently take any account of the correct years, the PCF8583 only provides 0-3 for the years, with 0 being a leap year - extra software routines will be required to do this, with the actual values stored in spare PCF8583 EEPROM memory, and updated when the year changes (remembering that the year might change while the processor is powered down, and the clock is running on it's back-up battery).

I2C A2D Board, and I2C Switch Board
Again, the A2D board uses the same basic I2C routines as before (but with a different chip address for the PCF8591) as with the I2C Clock Board the differences come in the manipulation of the data. As the board also includes an EEPROM socket this can be used to store samples from the A2D chip - with a single 24C256 we can store up to 32,768 eight bit samples - this introduces a slight 'snag', the 24C256 uses 'extended addressing', while the PCF8591 only uses 'standard addressing', however we can still use the same I2C routines by using a flag to tell the routines which addressing mode to use, simply switching the flag for the different chips - this flag switching becomes part of the reusable I2C routines.